package com.ruoyi.controller;

import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.ruoyi.common.annotation.RepeatSubmit;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.domain.*;
import com.ruoyi.enums.OrderStatusEnum;
import com.ruoyi.service.*;
import com.ruoyi.service.impl.AdvIncomedetailServiceImpl;
import com.ruoyi.utils.HttpUtils;
import com.ruoyi.utils.SimpleResult;
import com.ruoyi.utils.WechatPay2ValidatorForRequest;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.aspectj.weaver.loadtime.Aj;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URI;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Slf4j
@RestController
@RequestMapping("/system/wx-pay")
public class WxPayController {


    //Question 小程序支付完未主动查询 未同步 等待查单接口

    @Autowired
    private WxPayService wxPayService;

    @Autowired
    private Verifier verifier;

    @Autowired
    private IAdvOrdersService ordersService;
    @Autowired
    private IAdvIncomedetailService advIncomedetailService;
    @Autowired
    private IAdvIncomeService advIncomeService;
    @Autowired
    private WxAppService wxAppService;

    @GetMapping("/getaccess")
    public SimpleResult getAccess() {
        Map<String, String> accessToken = wxAppService.deliverGoods("orderNo", "openId");
        if(Objects.isNull(accessToken)) {
            return SimpleResult.error("获取失败");
        } else {
            System.out.println("即将返回的值" + accessToken);
            return SimpleResult.success(accessToken, "获取成功");
        }
    }

    @PostMapping("/jsapi")
    public AjaxResult jsapiPay(@RequestBody AdvOrdersdetail advOrdersdetail) throws IOException, NoSuchAlgorithmException, SignatureException, InvalidKeyException {
        System.out.println("JSAPI发起支付请求");
        System.out.println("AdvOrdersdetail--->"+advOrdersdetail);
        Map<String, Object> map = wxPayService.jsapiPay(advOrdersdetail);
        return AjaxResult.success(map);
    }


    /**
     * 支付通知
     * 微信支付通过支付通知接口将用户支付成功消息通知给商户
     */
    @PostMapping("/jsapi/notify")
    public String nativeNotify(HttpServletRequest request, HttpServletResponse response) {
        Gson gson = new Gson();
        Map<String, String> map = new HashMap<>();
        //应答对象
        System.out.println("支付通知");
        try {
            //处理通知参数
            String body = HttpUtils.readData(request);
            HashMap<String, Object> bodyMap = gson.fromJson(body, HashMap.class);
            String requestId = (String) bodyMap.get("id");
            System.out.println("支付通知的id ===> " + requestId);
            //log.info("支付通知的完整数据 ===> {}", body);
            //int a = 9 / 0;

            //签名的验证
            WechatPay2ValidatorForRequest wechatPay2ValidatorForRequest
                    = new WechatPay2ValidatorForRequest(verifier, requestId, body);
            if (!wechatPay2ValidatorForRequest.validate(request)) {
                System.out.println("通知验签失败");
                //失败应答
                response.setStatus(500);
                map.put("code", "ERROR");
                map.put("message", "通知验签失败");
                return gson.toJson(map);
            }
            System.out.println("通知验签成功");

            System.out.println("支付------------>"+"支付成功");
            //处理订单
            wxPayService.processOrder(bodyMap);

            //成功应答
            response.setStatus(200);
            map.put("code", "SUCCESS");
            map.put("message", "成功");
            return gson.toJson(map);

        } catch (Exception e) {
            log.error("支付通知接口错误{}",e);
            e.printStackTrace();
            //失败应答
            response.setStatus(500);
            map.put("code", "ERROR");
            map.put("message", "失败");
            return gson.toJson(map);
        }

    }

    //主动查单TODO
    @PostMapping("/jsapi/weQueryOrder")
    public Map<String,Object> weQueryOrder(){

        return new HashMap<>();
    }

    /**
     * 退款以及拒绝退款
     * @param advOrdersdetail
     * @return
     * @throws Exception
     */
    @PostMapping("/refunds")
    public AjaxResult refunds(@RequestBody AdvOrdersdetail advOrdersdetail) throws Exception {
        System.out.println("申请退款---->"+advOrdersdetail);
        String msg = "";
        if (advOrdersdetail.getRemark()==null&&!advOrdersdetail.getOrderStatus().equals(OrderStatusEnum.NOTPAY)&&!advOrdersdetail.getOrderStatus().equals(OrderStatusEnum.ORDER_OVER)){
            advOrdersdetail.setRemark("同意退款");
            msg =  "退款成功";
            wxPayService.refund(advOrdersdetail);
        }else {
            if (!advOrdersdetail.getOrderStatus().equals(OrderStatusEnum.NOTPAY)&&!advOrdersdetail.getOrderStatus().equals(OrderStatusEnum.ORDER_OVER)){
                wxPayService.NotReFunds(advOrdersdetail);
                msg =  "拒绝成功";
            }else {
                msg = "状态异常";
            }
        }
        return AjaxResult.success(msg);
    }

    /**
     * 退款结果通知
     * 退款状态改变后，微信会把相关退款结果发送给商户。
     */
    @PostMapping("/refunds/notify")
    public String refundsNotify(HttpServletRequest request, HttpServletResponse response) {
        System.out.println("退款通知执行");
        Gson gson = new Gson();
        Map<String, String> map = new HashMap<>();//应答对象
        try {

            //处理通知参数
            String body = HttpUtils.readData(request);

            Map<String, Object> bodyMap = gson.fromJson(body, HashMap.class);

            String requestId = (String) bodyMap.get("id");

            System.out.println("支付通知的id ===> " + requestId);

            //签名的验证
            WechatPay2ValidatorForRequest wechatPay2ValidatorForRequest
                    = new WechatPay2ValidatorForRequest(verifier, requestId, body);

            if (!wechatPay2ValidatorForRequest.validate(request)) {
                System.out.println("通知验签失败");
                //失败应答
                response.setStatus(500);
                map.put("code", "ERROR");
                map.put("message", "通知验签失败");
                return gson.toJson(map);
            }

            System.out.println("通知验签成功");

            //处理退款单
            wxPayService.processRefund(bodyMap);

            //成功应答
            response.setStatus(200);
            map.put("code", "SUCCESS");
            map.put("message", "成功");
            return gson.toJson(map);

        } catch (Exception e) {
            log.error("退款结果通知{}",e);
            e.printStackTrace();
            //失败应答
            response.setStatus(500);
            map.put("code", "ERROR");
            map.put("message", "失败");
            return gson.toJson(map);
        }
    }

    /**
     * 支付完成更改支付状态
     * @param advOrdersdetail
     * @return
     * @throws IOException
     */
    @PostMapping("/payOver")
    public AjaxResult payOver(@RequestBody AdvOrdersdetail advOrdersdetail) throws IOException {
        AdvOrders advOrders = ordersService.selectOrderPayByOrderId(advOrdersdetail.getAdvOrdersId());
        wxPayService.checkOrderStatus(advOrders.getOrdersno());
        System.out.println("advOrders------>"+advOrdersdetail);
        return AjaxResult.success();
    }

    /**
     * 营销会员添加分账参数
     */
    @PostMapping("/AddShare")
    public AjaxResult AddShare(@RequestBody  AdvMembers advMembers) throws IOException {
        wxPayService.exeAddShare(advMembers);
        return AjaxResult.success();
    }

    /**
     * 申请分账
     */
    @PostMapping("/payShare")
    public AjaxResult payShare(@RequestBody AdvIncome advIncome) throws IOException {
        System.out.println("advIncome-------->"+advIncome);
        List<AdvIncomedetail> list = advIncomedetailService.getIncomedetail(advIncome.getAdvIncomeId()+"");
        boolean tag =  wxPayService.exePayShare(advIncome,list);
        return AjaxResult.success(tag);
    }

    /**
     * 批量分账
     * @param advIncomeIds
     * @return
     * @throws IOException
     */
    @PostMapping("/batchPayShare")
    public AjaxResult batchPayShare(@RequestBody List<Long> advIncomeIds) throws IOException{
        List<AdvIncome> advIncomeList = advIncomeService.selectAdvIncomeByIds(advIncomeIds);
        for (AdvIncome advIncome : advIncomeList) {
            List<AdvIncomedetail> list = advIncomedetailService.getIncomedetail(advIncome.getAdvIncomeId()+"");
            wxPayService.exePayShare(advIncome,list);
        }
        return AjaxResult.success();
    }
}
